import wmi
import datetime
import json
import winreg


class Base:
    """扫描的类"""

    @staticmethod
    def get_register_info():
        """获取注册信息的方法"""
        # 获取主板id
        board_id = Base.get_board_id()
        # 获取电脑的名字
        computer_name = Base.get_computer_name()
        return "{'boardId':'%s','computerName':'%s'}" % (board_id, computer_name)

    @staticmethod
    def get_board_id():
        """获取主板的ID"""
        # 获取wmi对象
        c = wmi.WMI()
        # 读取主板的信息
        board_info = c.Win32_BaseBoard()
        # 获取具体的主板id
        board_id = board_info[0].SerialNumber.strip()
        return board_id

    @staticmethod
    def get_computer_name():
        """获取电脑的名字"""
        # 获取wmi对象
        c = wmi.WMI()
        wmi_win32_operating_system = c.Win32_OperatingSystem()[0]
        computer_name = wmi_win32_operating_system.CSName
        return computer_name

    @staticmethod
    def get_base_info():
        """获取当前设备的基本信息"""
        w = wmi.WMI()
        # 获取计算机运行环境信息
        wmi_win32_operating_system = w.Win32_OperatingSystem()[0]
        # 获取计算机CPU数量,内存大小,主板相关信息
        wmi_win32_computer_system = w.Win32_ComputerSystem()[0]
        # 用于获取CPU详细信息
        wmi_win32_processor = w.Win32_Processor()[0]
        # 组装数据
        info = {
            "caption": wmi_win32_operating_system.Caption,  # 操作系统版本
            "CSName": wmi_win32_operating_system.CSName,  # 计算机名字
            "localDateTime": str(
                datetime.datetime.strptime(str(str(wmi_win32_operating_system.LocalDateTime).split('.')[0]),
                                           '%Y%m%d%H%M%S')),  # 获取系统本地时间
            "lastBootUpTime": str(
                datetime.datetime.strptime(str(str(wmi_win32_operating_system.LastBootUpTime).split('.')[0]),
                                           '%Y%m%d%H%M%S')),  # 获取系统上次启动时间
            "OSArchitecture": wmi_win32_operating_system.OSArchitecture,  # 获取操作系统类型(32bit/64bit)
            "MUILanguages": wmi_win32_operating_system.MUILanguages[0],  # 获取操作系统语言版本
            "serialNumber": wmi_win32_operating_system.SerialNumber,  # 获取操作系统序列号
            "numberOfProcessors": wmi_win32_computer_system.NumberOfProcessors,
            # 获取cpu数量 这里获取的是外部硬件规格，家用机电脑，主板只能安装一个cpu规格，所有获取为1
            "manufacturer": wmi_win32_computer_system.Manufacturer,  # 获取主板厂商信息
            "boardId": w.Win32_BaseBoard()[0].SerialNumber.strip(),  # 主板ID
            "model": wmi_win32_computer_system.Model,  # 获取主板型号
            "systemType": wmi_win32_computer_system.SystemType,  # 获取主板架构类型
            "totalPhysicalMemory": int(wmi_win32_computer_system.TotalPhysicalMemory) / 1024 / 1024,  # 获取内存容量
            "cpuName": wmi_win32_processor.Name,  # 获取cpu类型
            "cpuMaxClockSpeed": wmi_win32_processor.MaxClockSpeed,  # 获取操作系统CPU主频
            "cpuNumberOfCores": wmi_win32_processor.NumberOfCores,  # 获取CPU核心数量
            "cpuDataWidth": wmi_win32_processor.DataWidth,  # 获取计算机的CPU数据宽度
            "cpuSocketDesignation": wmi_win32_processor.SocketDesignation,  # 获取主板cpu接口类型
            "cpuL2CacheSize": wmi_win32_processor.L2CacheSize,  # 获取cpu二级缓存大小
            "cpuL3CacheSize": wmi_win32_processor.L3CacheSize  # 获取cpu三级缓存大小
        }
        return json.dumps(info)

    @staticmethod
    def get_install_soft():
        """扫描安装软件列表"""
        # 定义注册表安装卸载软件检测位置，下列两种位置都可以找到
        # r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
        # r'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
        # r: 表示去掉转义机制
        sub_key = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'

        # 获取句柄handle(把注册表对象转换为python对象)
        key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, sub_key, 0, winreg.KEY_ALL_ACCESS)
        # print(key)
        software_name = []
        # 通过winreg.QueryInfoKey(key)[0]获取当前注册表中的总个数
        for j in range(0, winreg.QueryInfoKey(key)[0] - 1):
            try:
                # 获取应用软件的尾缀名称(一般情况下都是软件名称，但是有特例：{69CFC76B-3434-4919-8885-BA7960725137})
                key_name = winreg.EnumKey(key, j)
                # print(key_name)
                # 组装完整的注册表软件路径
                key_path = sub_key + '\\' + key_name
                # print(key_path)
                each_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_path, 0, winreg.KEY_ALL_ACCESS)
                # print(each_key)

                display_name, rgz = winreg.QueryValueEx(each_key, 'DisplayName')
                # print(rgz)
                # DisplayName = DisplayName.encode('utf-8')
                software_name.append(display_name)
            except WindowsError:
                pass

        software_name = list(set(software_name))
        software_name = sorted(software_name)
        return json.dumps(software_name)

    @staticmethod
    def get_network_info():
        """获取网络配置信息"""
        # 实例化wmi类
        w = wmi.WMI()
        #  配置及获取网络连接相关信息
        wmi_win32_network_adapter_configuration = w.Win32_NetworkAdapterConfiguration(IPEnabled=1)
        return json.dumps(wmi_win32_network_adapter_configuration, default=Base.network2dict)

    # 网络信息转dict
    @staticmethod
    def network2dict(obj):
        info = {
            "ipAddress": obj.IPAddress[0],
            "netMask": obj.IPSubnet[0],
            # "gateway": obj.DefaultIPGateway[0],
            "mac": obj.MACAddress
        }
        # 判断是否有dns
        # if hasattr(obj, "DNSServerSearchOrder"):
        #     info["firstDNS"] = obj.DNSServerSearchOrder[0]
        #     info["secDNS"] = obj.DNSServerSearchOrder[1]
        return info

    @staticmethod
    def get_service_info():
        """获取服务信息"""
        w = wmi.WMI()
        # 获取服务相关信息
        wmi_win32_service = w.Win32_Service()
        return json.dumps(wmi_win32_service, default=Base.service2dict)

    # 服务基线转dict
    @staticmethod
    def service2dict(obj):
        # 处理描述信息
        description = str(obj.Description)
        description = description.replace('\\"', '')
        return {
            "acceptPause": obj.AcceptPause,
            "acceptStop": obj.AcceptStop,
            "caption": obj.Caption,
            "checkPoint": obj.CheckPoint,
            "creationClassName": obj.CreationClassName,
            "delayedAutoStart": obj.DelayedAutoStart,
            "description": description,
            "desktopInteract": obj.DesktopInteract,
            "displayName": obj.DisplayName,
            "errorControl": obj.ErrorControl,
            "exitCode": obj.ExitCode,
            "name": obj.Name,
            "pathName": obj.PathName,
            "processId": obj.ProcessId,
            "serviceSpecificExitCode": obj.ServiceSpecificExitCode,
            "serviceType": obj.ServiceType,
            "started": obj.Started,
            "startMode": obj.StartMode,
            "state": obj.State,
            "status": obj.Status,
            "systemCreationClassName": obj.SystemCreationClassName,
            "systemName": obj.SystemName,
            "tagId": obj.TagId,
            "waitHint": obj.WaitHint
        }

